﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
namespace Region
{
    public interface ITreeValue
    {
        object ItemID { get; }
        object ItemParentID { get; }
        String ItemCaption { get; }
    }
    public class ObjectFormUtil
    {
        struct TTEditorInfo
        {
            public Control Editor;
            public String PoleName;
            public Object ExProccessor;
        }
        List<TTEditorInfo> m_Editors;
        IReadWriteObject m_Object;
        Engine m_engine;
        public ObjectFormUtil(Engine engine, IReadWriteObject Object)
        {
            m_Object = Object;
            m_engine = engine;
            m_Editors = new List<TTEditorInfo>();            
        }
        public void AddEditor(Control Editor, String PoleName) { AddEditor(Editor, PoleName, null); }
        public void AddEditor(Control Editor, String PoleName, Object ExProccessor)
        {            
            TTEditorInfo  EI = new TTEditorInfo();
            EI.Editor = Editor;
            EI.PoleName = PoleName;
            EI.ExProccessor = ExProccessor;
            m_Editors.Add(EI);
        }
        public void set()
        {
            var newPoles = new Dictionary<String, Object>();
            foreach (TTEditorInfo Info in m_Editors)
            {
                EPoleType PoleType = m_Object.getPoleType(Info.PoleName);
                Boolean Access = m_Object.poleAccess(Info.PoleName);
                if (Info.Editor is NumericUpDown)
                {
                    NumericUpDown Editor = (NumericUpDown)Info.Editor;
                    Decimal Value = Editor.Value;
                    switch (PoleType)
                    {
                        case EPoleType.Int32: newPoles[Info.PoleName] = (Int32)Value; break;
                        case EPoleType.Int64: newPoles[Info.PoleName] = (Int64)Value; break;
                        case EPoleType.String: newPoles[Info.PoleName] = Value.ToString(); break;
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }
                }
                else if (Info.Editor is DateTimePicker)
                {
                    var Editor = (DateTimePicker)Info.Editor;                    
                    switch (PoleType)
                    {
                      case EPoleType.Date:
                      case EPoleType.RegionDate:
                      {
                        var Value = new RegionDate(Editor.Value);
                        if (Editor.ShowCheckBox) Value.Epmty=!Editor.Checked;                        
                            newPoles[Info.PoleName] = (RegionDate)Value;                           
                      }
                      break;
                      default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }
                }
                else if (Info.Editor is TextBox)
                {
                    TextBox Editor = (TextBox)Info.Editor;
                    String Value = Editor.Text; 
                    switch (PoleType)
                    {
                        case EPoleType.Int32: { Int32 V = 0; Int32.TryParse(Value, out V); newPoles[Info.PoleName] = (Int32)V; } break;
                        case EPoleType.Int64: { Int64 V = 0; Int64.TryParse(Value, out V); newPoles[Info.PoleName] = (Int64)V; } break;
                        case EPoleType.String: newPoles[Info.PoleName] = (String)Value; break;
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }
                } 
                else if (Info.Editor is ComboBox)
                {
                    ComboBox Editor = (ComboBox)Info.Editor;
                    Object Value = ((Utils.ListItemValue)Editor.SelectedItem).Value;
                    switch (PoleType)
                    {
                        case EPoleType.Bool: newPoles[Info.PoleName] = (Boolean)Value; break;
                        case EPoleType.Int32: newPoles[Info.PoleName] = (Int32)Value; break;
                        case EPoleType.Int64: newPoles[Info.PoleName] = (Int64)Value; break;
                        case EPoleType.String: newPoles[Info.PoleName] = (String)Value; break;
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }
                }
                else if (Info.Editor is ListBox)
                {
                    ListBox Editor = (ListBox)Info.Editor;
                    Object Value = ((Utils.ListItemValue)Editor.SelectedItem).Value;
                    switch (PoleType)
                    {
                        case EPoleType.Bool: newPoles[Info.PoleName] = (Boolean)Value; break;
                        case EPoleType.Int32: { newPoles[Info.PoleName] = (Int32)Value; } break;
                        case EPoleType.Int64: { newPoles[Info.PoleName] = (Int64)Value; } break;
                        case EPoleType.String: { newPoles[Info.PoleName] = (String)Value; } break;
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }
                }
                else if (Info.Editor is TreeComboBox)
                {
                    TreeComboBox Editor = (TreeComboBox)Info.Editor;
                    Object Value = Editor.SelectItemID();
                    switch (PoleType)
                    {
                        case EPoleType.Int32: { newPoles[Info.PoleName] = (Int32)Value; } break;
                        case EPoleType.Int64: { newPoles[Info.PoleName] = (Int64)Value; } break;
                        case EPoleType.String: { newPoles[Info.PoleName] = (String)Value; } break;
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }
                    
                }
                else if (Info.Editor is UserSelector)
                {
                    UserSelector Editor = (UserSelector)Info.Editor;
                    Object Value = Editor.UserID;
                    switch (PoleType)
                    {
                        case EPoleType.Int32: { newPoles[Info.PoleName] = (Int32)Value; } break;
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }                  
                }
                else if (Info.Editor is OtdelSelector)
                {
                    OtdelSelector Editor = (OtdelSelector)Info.Editor;
                    Object Value = Editor.OtdelID;
                    switch (PoleType)
                    {
                        case EPoleType.Int32: { newPoles[Info.PoleName] = (Int32)Value; } break;
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }                  
                }
                else if (Info.Editor is CheckBox)
                {
                    CheckBox Editor = (CheckBox)Info.Editor;
                    Boolean Value = Editor.Checked;
                    switch (PoleType)
                    {
                        case EPoleType.Bool: { newPoles[Info.PoleName] = (Boolean)Value; } break;
                        case EPoleType.Int32: { newPoles[Info.PoleName] =  (Int32)(Value ? 1 : 0); } break;
                        case EPoleType.Int64: { newPoles[Info.PoleName] =  (Int64)(Value ? 1 : 0); } break;
                        
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]");
                    }

                }
                else throw new Exception("Не реализован редактор поля '"+Info.PoleName+"' для:" + Info.Editor.GetType().FullName);
                
            }
            m_Object.setPoles(newPoles);
        }                
        public void get()
        {
            IDictionary<String,Object> Poles = m_Object.getPoles();
            foreach (TTEditorInfo Info in m_Editors)
            {
                EPoleType PoleType = m_Object.getPoleType(Info.PoleName);
                Boolean Access = m_Object.poleAccess(Info.PoleName);
                if (Info.Editor is NumericUpDown)
                {
                    NumericUpDown Editor = (NumericUpDown)Info.Editor;
                    
                    switch (PoleType)
                    {
                        case EPoleType.Int32:
                        {
                          Editor.Maximum=Int32.MaxValue;
                          Editor.Minimum=Int32.MinValue;
                          Editor.Value = (Int32)Poles[Info.PoleName]; Editor.Enabled = Access; break;
                        }
                        case EPoleType.Int64:
                        {
                          Editor.Maximum=Int64.MaxValue;
                          Editor.Minimum=Int64.MinValue;
                          Editor.Value = (Int64)Poles[Info.PoleName]; Editor.Enabled = Access; break;
                        }
                        case EPoleType.String:
                        {
                          Editor.Maximum=Decimal.MaxValue;
                          Editor.Minimum=Decimal.MinValue;
                          Decimal Value = 0; Decimal.TryParse((String)Poles[Info.PoleName], out Value); Editor.Value = Value; Editor.Enabled = Access; break;
                        }
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }
                }
                else if (Info.Editor is DateTimePicker)
                {
                    DateTimePicker Editor = (DateTimePicker)Info.Editor;
                    switch (PoleType)
                    {
                        case EPoleType.Date:
                        case EPoleType.RegionDate:
                            RegionDate Value = (RegionDate)Poles[Info.PoleName];
                            Editor.Enabled = Access;
                            if (Value.Epmty) Editor.Value = DateTime.Now; else Editor.Value = Value;
                            if (Editor.ShowCheckBox) Editor.Checked = !Value.Epmty;
                            break;
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }
                }
                else if (Info.Editor is TextBox)
                {                    
                    TextBox Editor = (TextBox)Info.Editor;
                    switch (PoleType)
                    {
                        case EPoleType.Int32: Editor.Text = Poles[Info.PoleName].ToString(); Editor.Enabled = Access; break;
                        case EPoleType.Int64: Editor.Text = Poles[Info.PoleName].ToString(); Editor.Enabled = Access; break;
                        case EPoleType.String: Editor.Text = (String)Poles[Info.PoleName]; Editor.Enabled = Access; break;
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }
                }
                else if (Info.Editor is ComboBox)
                {
                    ComboBox Editor = (ComboBox)Info.Editor;                    
                    Dictionary<Object, String> List = new Dictionary<Object, String>();
                    //if (Info.ExProccessor is Dictionary<Int16, String>) foreach (var i in (Dictionary<Int16, String>)Info.ExProccessor) List[i.Key] = i.Value;
                    if (Info.ExProccessor is Dictionary<Boolean, String>) foreach (var i in (Dictionary<Boolean, String>)Info.ExProccessor) List[i.Key] = i.Value;
                    if (Info.ExProccessor is Dictionary<Int32, String>) foreach (var i in (Dictionary<Int32, String>)Info.ExProccessor) List[i.Key] = i.Value;
                    if (Info.ExProccessor is Dictionary<Int64, String>) foreach (var i in (Dictionary<Int64, String>)Info.ExProccessor) List[i.Key] = i.Value;
                    if (Info.ExProccessor is Dictionary<Object, String>) List = (Dictionary<Object, String>)Info.ExProccessor;
                    
                    Editor.Items.Clear();
                    foreach (var i in List) Editor.Items.Add(new Utils.ListItemValue(i.Value, i.Key));
                    switch (PoleType)
                    {
                        case EPoleType.Bool: { Boolean Value = (Boolean)Poles[Info.PoleName]; Editor.SelectedItem = new Utils.ListItemValue(List[Value], Value); Editor.Enabled = Access; } break;
                        case EPoleType.Int32: { Int32 Value = (Int32)Poles[Info.PoleName]; Editor.SelectedItem = new Utils.ListItemValue(List[Value], Value); Editor.Enabled = Access; } break;
                        case EPoleType.Int64: { Int64 Value = (Int64)Poles[Info.PoleName]; Editor.SelectedItem = new Utils.ListItemValue(List[Value], Value); Editor.Enabled = Access; } break;
                        case EPoleType.String: {String Value = (String)Poles[Info.PoleName];Editor.SelectedItem = new Utils.ListItemValue(List[Value], Value);Editor.Enabled = Access;} break;
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }
                }
                else if (Info.Editor is ListBox)
                {
                    ListBox Editor = (ListBox)Info.Editor;                    
                    Dictionary<Object, String> List = new Dictionary<Object, String>();
                    //if (Info.ExProccessor is Dictionary<Int16, String>) foreach (var i in (Dictionary<Int16, String>)Info.ExProccessor) List[i.Key] = i.Value;
                    if (Info.ExProccessor is Dictionary<Boolean, String>) foreach (var i in (Dictionary<Boolean, String>)Info.ExProccessor) List[i.Key] = i.Value;
                    if (Info.ExProccessor is Dictionary<Int32, String>) foreach (var i in (Dictionary<Int32, String>)Info.ExProccessor) List[i.Key] = i.Value;
                    if (Info.ExProccessor is Dictionary<Int64, String>) foreach (var i in (Dictionary<Int64, String>)Info.ExProccessor) List[i.Key] = i.Value;
                    if (Info.ExProccessor is Dictionary<Object, String>) List = (Dictionary<Object, String>)Info.ExProccessor;
                    Editor.Items.Clear();
                    foreach (var i in List) Editor.Items.Add(new Utils.ListItemValue(i.Value, i.Key));
                    switch (PoleType)
                    {
                        case EPoleType.Bool: { Boolean Value = (Boolean)Poles[Info.PoleName]; Editor.SelectedItem = new Utils.ListItemValue(List[Value], Value); Editor.Enabled = Access; } break;
                        case EPoleType.Int32: { Int32 Value = (Int32)Poles[Info.PoleName]; Editor.SelectedItem = new Utils.ListItemValue(List[Value], Value); Editor.Enabled = Access; } break;
                        case EPoleType.Int64: { Int64 Value = (Int64)Poles[Info.PoleName]; Editor.SelectedItem = new Utils.ListItemValue(List[Value], Value); Editor.Enabled = Access; } break;
                        case EPoleType.String: { String Value = (String)Poles[Info.PoleName]; Editor.SelectedItem = new Utils.ListItemValue(List[Value], Value); Editor.Enabled = Access; } break;
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }
                }
                else if (Info.Editor is TreeComboBox)
                {
                    TreeComboBox Editor = (TreeComboBox)Info.Editor;                    
                    Dictionary<Object, ITreeValue> List = new Dictionary<Object, ITreeValue>();
                    //if (Info.ExProccessor is Dictionary<Int16, Object>) foreach (var i in (Dictionary<Int16, Object>)Info.ExProccessor) if (i.Value is ITreeValue) List[i.Key] = (ITreeValue)i.Value;
                    if (Info.ExProccessor is Dictionary<Int32, Object>) foreach (var i in (Dictionary<Int32, Object>)Info.ExProccessor) if (i.Value is ITreeValue) List[i.Key] = (ITreeValue)i.Value;
                    if (Info.ExProccessor is Dictionary<Int64, Object>) foreach (var i in (Dictionary<Int64, Object>)Info.ExProccessor) if (i.Value is ITreeValue) List[i.Key] = (ITreeValue)i.Value;
                    if (Info.ExProccessor is Dictionary<String, Object>) foreach (var i in (Dictionary<String, Object>)Info.ExProccessor) if (i.Value is ITreeValue) List[i.Key] = (ITreeValue)i.Value;
                    if (Info.ExProccessor is Dictionary<Object, Object>) foreach (var i in (Dictionary<Object, Object>)Info.ExProccessor) if (i.Value is ITreeValue) List[i.Key] = (ITreeValue)i.Value;
                
                    Editor.Clear();
                    foreach (var i in List) 
                      Editor.Add(i.Value.ItemParentID, i.Value.ItemID, i.Value.ItemCaption);
                    Editor.ShowTreeList();
                    switch (PoleType)
                    {
                        case EPoleType.Int32: { Editor.SelectItemID((Int32)Poles[Info.PoleName]); Editor.Enabled = Access; } break;
                        case EPoleType.Int64: { Editor.SelectItemID((Int64)Poles[Info.PoleName]); Editor.Enabled = Access; } break;
                        case EPoleType.String: { Editor.SelectItemID((String)Poles[Info.PoleName]); Editor.Enabled = Access; } break;
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                    }
                    
                }
                else if (Info.Editor is UserSelector)
                {
                  UserSelector Editor = (UserSelector)Info.Editor;
                  if (Info.ExProccessor is UserList) 
                    Editor.userList = (UserList)Info.ExProccessor;
                  switch (PoleType)
                  {
                      case EPoleType.Int32: { Editor.UserID = (Int32)Poles[Info.PoleName]; Editor.Enabled = Access; } break;
                      default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                  }
                }
                else if (Info.Editor is OtdelSelector)
                {
                  OtdelSelector Editor = (OtdelSelector)Info.Editor;
                  if (Info.ExProccessor is OtdelList) 
                    Editor.otdelList = (OtdelList)Info.ExProccessor;
                  switch (PoleType)
                  {
                      case EPoleType.Int32: { Editor.OtdelID = (Int32)Poles[Info.PoleName]; Editor.Enabled = Access; } break;
                      default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]"); 
                  }
                }
                else if (Info.Editor is CheckBox)
                {
                    CheckBox Editor = (CheckBox)Info.Editor;
                    switch (PoleType)
                    {
                        case EPoleType.Bool: Editor.Checked = (Boolean)Poles[Info.PoleName]; Editor.Enabled = Access; break;
                        case EPoleType.Int32: Editor.Checked = (Int32)Poles[Info.PoleName] > 0; Editor.Enabled = Access; break;
                        case EPoleType.Int64: Editor.Checked = (Int64)Poles[Info.PoleName] > 0; Editor.Enabled = Access; break;
                        
                        default: throw new Exception("Для " + Info.Editor.GetType().FullName + " тип данных поля '" + Info.PoleName + "' не поддерживается [EPoleType." + PoleType.ToString() + "]");
                    }

                }
                else throw new Exception("Не реализован редактор поля '" + Info.PoleName + "' для:" + Info.Editor.GetType().FullName);
            }
        }
    }
}
